package structs

import "time"

// BVResult 错误码
type BVResult int32

// BVResult* 错误码定义
const (
	BVResultSuccess    BVResult = 0
	BVResultFailed     BVResult = 1
	BVResultNotFound   BVResult = 2
	BVResultExist      BVResult = 3
	BVResultErrorParam BVResult = 4
)

type (
	FileState string
)

const (
	FileStateFileIdMatched  FileState = "file_id_matched"  // fileId匹配, 文件已存在, 秒传
	FileStatePreHashMatched FileState = "pre_hash_matched" // 预哈希(sha256)匹配, 下一步匹配文件哈希(sha256)
	FileStateContentMatched FileState = "content_matched"  // 文件内容匹配, 文件已存在, 秒传
	FileStateNewFile        FileState = "new_file"         // 新文件
)

type JsonCreateRequest struct {
	Name        string         `json:"name" binding:"required"`                        // 文件名称，utf8编码 最长 256 字节
	Size        int            `json:"size" binding:"required"`                        // 文件大小，单位为 byte
	PreHash     string         `json:"pre_hash" binding:"required"`                    // 针对大文件 sha256 计算非常耗时的情况， 可以先在读取文件的前1k的 sha256， 如果前1k的 sha256 没有匹配的， 那么说明文件无法做秒传， 如果1k的 sha256 有匹配再计算文件 sha256 进行秒传，这样有效边避免无效的 sha256 计算。
	ContentHash string         `json:"content_hash"`                                   // 文件内容 sha256 值 (小文件可以计算携带, 更快判断秒传)
	PartSize    int            `json:"part_size" binding:"required" default:"4194304"` // 分片大小, 单位 byte(必须是64KB整数倍) 推荐值: 4~10MB
	PartCount   int            `json:"part_count" binding:"required"`                  // 分片数
	Extra       *JsonCreateExt `json:"extra" binding:"required"`                       // 扩展数据
}

type JsonCreateExt struct {
	FileId    string  `json:"fileId"`                       // 文件ID, 指定存储的FileID(不推荐)
	UserId    string  `json:"userId"`                       // 用户ID
	PuId      string  `json:"puId" binding:"required"`      // 设备ID
	BeginTime int64   `json:"beginTime" binding:"required"` // 开始时间戳 单位秒
	EndTime   int64   `json:"endTime" binding:"required"`   // 接收时间戳 单位秒
	Channel   int     `json:"channel"`                      // 通道号
	FileType  string  `json:"fileType" binding:"required"`  // 文件类型 ["video", "audio", "image", "gps"]
	Lat       float64 `json:"lat"`                          // 纬度, 单位: 度
	Lng       float64 `json:"lng"`                          // 经度, 单位: 度
	Desc1     string  `json:"desc1"`                        // 描述1
	Desc2     string  `json:"desc2"`                        // 描述2
	Mark      bool    `json:"mark"`                         // 重点文件标记
}

type JsonCreateReply struct {
	Code     BVResult `json:"code" binding:"required"` // 错误码
	Msg      string   `json:"msg" binding:"required"`  // 信息
	Duration time.Duration

	FileState          FileState        `json:"file_state" binding:"required"` // 文件状态
	FileIdMatched      *JsonFileMatched `json:"file_id_matched,omitempty"`     // [秒传] file_state 为 file_id_matched 时有效
	ContentHashMatched *JsonFileMatched `json:"content_matched,omitempty"`     // [秒传] file_state 为 content_matched 时有效
	NewFile            *JsonNewFile     `json:"new_file,omitempty"`            // [新上传] file_state 为 new_file 时有效

	SameUpload *JsonSameUpload `json:"same,omitempty"` // 如果存在相同上传, 上传者的信息
}

type JsonSameUpload struct {
	NameSame    bool `json:"name_same"`     // 名称相同
	SizeSame    bool `json:"size_same"`     // 文件大小相同
	PreHashSame bool `json:"pre_hash_same"` // 预哈希(sha256)相同

	UploaderRequest *JsonCreateRequest `json:"uploader_request"` // 上传者的请求
	UploaderId      string             `json:"uploader_id"`      // 上传者ID
}

type JsonNewFile struct {
	UploadId string `json:"upload_id" binding:"required"` // 传输ID
	FileId   string `json:"fileId" binding:"required"`    // 文件ID
}

type JsonFileMatched struct {
	FileId      string `json:"file_id" binding:"required"`  // 文件ID
	Name        string `json:"name" `                       // 文件名称
	Size        int    `json:"size"`                        // 文件大小, 单位为 byte
	ContentHash string `json:"content_hash"`                // 文件 hash
	PreHash     string `json:"pre_hash" binding:"required"` // 文件的前1k的sha256
}

type JsonListUploadedPartsReply struct {
	Code     BVResult `json:"code" binding:"required"`
	Msg      string   `json:"msg" binding:"required"`
	Duration time.Duration
	Data     *JsonListUploadedPartsPayload `json:"data,omitempty"`
}

type JsonListUploadedPartsPayload struct {
	UploadId      string              `json:"upload_id" binding:"required"` // 文件创建获取的upload_id
	PartSize      int                 `json:"part_size" binding:"required"` // 分片大小, 单位 byte(64KB整数倍)
	Speed         int                 `json:"speed"`                        // 如果在传输速度 bytes/s
	UploadedParts []*JsonUploadedPart `json:"uploaded_parts"`               // 分片列表
}

type JsonUploadedPart struct {
	PartNumber  int    `json:"part_number" binding:"required"`              // 分片编号, [0, n]
	ChunkSize   int    `json:"chunk_size" binding:"required"`               // 本分片数据大小 单位bytes
	TransSize   int    `json:"trans_size" binding:"required"`               // 已传输大小 bytes
	Complete    bool   `json:"complete" binding:"required"`                 // 分片是否完成
	IsTrans     bool   `json:"is_trans" binding:"required"`                 // 是否在传输中
	Speed       int    `json:"speed"`                                       // 如果在传输速度 bytes/s
	TransString string `json:"trans_string,omitempty" swaggerignore:"true"` //
}

type JsonPutPartReply struct {
	Code BVResult `json:"code" binding:"required"`
	Msg  string   `json:"msg" binding:"required"`

	Duration time.Duration
}

type JsonCompleteReply struct {
	Code     BVResult `json:"code" binding:"required"`
	Msg      string   `json:"msg" binding:"required"`
	Duration time.Duration
	Data     *JsonCompletePayload `json:"data,omitempty"`
}

type JsonCompletePayload struct {
	FileId      string `json:"file_id" binding:"required"`      // 文件ID
	Name        string `json:"name" binding:"required"`         // 文件名称，按照 utf8 编码最长 1024 字节
	Size        int    `json:"size" binding:"required"`         // 文件大小，单位为 byte
	ContentHash string `json:"content_hash" binding:"required"` // 文件内容 hash 值
}

type JsonCancelReply struct {
	Code     BVResult `json:"code" binding:"required"`
	Msg      string   `json:"msg" binding:"required"`
	Duration time.Duration
}

type JsonListUploaderRequest struct {
	Page     int                     `json:"page" minimum:"0"`                                       // 分页, 第一页: 0, 第二页: 1, 第三页: 2 ...
	PageSize int                     `json:"pageSize" minimum:"1" maximum:"1000" binding:"required"` // 分页大小 > 0
	Filter   *JsonListUploaderFilter `json:"filter"`                                                 // 过滤
}

type JsonListUploaderFilter struct {
	PuId string `json:"puId"`
}

type JsonListUploader struct {
	Code     BVResult `json:"code" binding:"required"`
	Msg      string   `json:"msg" binding:"required"`
	Duration time.Duration
	PageInfo *JsonPageInfo            `json:"pageInfo,omitempty"`
	Data     []*JsonListUploadPayload `json:"data,omitempty"`
	Rates    *JsonTotalRates          `json:"rates,omitempty"` // 总带宽信息
}

type JsonTotalRates struct {
	Rates int    `json:"rates"` // 实时总速度
	Limit int    `json:"limit"` // 总带宽限制
	Info  string `json:"info" swaggerignore:"true"`
}

type JsonPageInfo struct {
	Page       int `json:"page"`
	PageSize   int `json:"pageSize"`
	TotalCount int `json:"totalCount"`
}

type JsonListUploadPayload struct {
	CreateTime  int64             `json:"create_time"`                       // 创建时间
	UploadId    string            `json:"upload_id"`                         // 上传任务ID
	FileId      string            `json:"file_id"`                           // 文件ID
	Speed       int               `json:"speed"`                             // 速度 bytes/s
	TransSize   int               `json:"trans_size"`                        // 已传输大小 bytes
	TransString string            `json:"trans_string" swaggerignore:"true"` // 传输信息
	Request     JsonCreateRequest `json:"request"`                           // 上传信息
}

type JsonUploadInfo struct {
	CreateTime int64             `json:"createTime"` // 创建时间
	UploadId   string            `json:"uploadId"`   // 上传任务ID
	FileId     string            `json:"fileId"`     // 文件ID
	Request    JsonCreateRequest `json:"request"`

	UploadFilename string                 `json:"uploadFilename"`
	Chunks         []*JsonUploadChuckInfo `json:"chunks"`
}

type JsonUploadChuckInfo struct {
	PartNumber int    `json:"partNumber"` // 分片编号, [0, n]
	PartSize   int    `json:"partSize"`   // 分片大小 单位 byte(64KB整数倍)
	ChunkSize  int    `json:"chunkSize"`  // 本分片数据量(最后一分片数据大小)
	Hash       string `json:"hash"`       // 分片hash
	Complete   bool   `json:"complete"`   // 分片状态
	TransSize  int    `json:"transSize"`  // 传输大小 bytes
}
